use chrono::{DateTime, Duration, Utc};

use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct MyClaims {
    pub id: u64,
    pub username: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
    pub id: u64,
    pub username: String,
    pub exp: DateTime<Utc>,
}

const JWT_SECRET: &str = "Rtg8BPKNEfeotynhdfe234aJWNLijxR42qRgq0iBb5";
// 签名
pub fn sign(c: MyClaims) -> Result<String, jsonwebtoken::errors::Error> {
    let now = Utc::now();
    let expiration_time = now + Duration::hours(1);
    let my_claims = Claims {
        id: c.id,
        username: c.username,
        exp: expiration_time,
    };
    let token = encode(
        &Header::default(),
        &my_claims,
        &EncodingKey::from_secret(JWT_SECRET.as_ref()),
    )?;
    Ok(token)
}

// 解密 token
pub fn parse(token: &str) -> Result<Claims, jsonwebtoken::errors::Error> {
    let token_res = decode::<Claims>(
        token,
        &DecodingKey::from_secret(JWT_SECRET.as_ref()),
        &Validation::default(),
    )?;
    Ok(token_res.claims)
}
